package com.witer.colorswitch.view;


public class CGGeometryLib {  
      

    public static double getDistanceBetween2Points(CGPoint p0, CGPoint p1) {  
        double distance = Math.sqrt(Math.pow(p0.y - p1.y, 2) + Math.pow(p0.x - p1.x, 2));
        return distance;  
    }  
      

    public static CGPoint getProjectivePoint(CGPoint p, CGLine l) {  
        CGPoint target = null;  
        if(l.iskExists()) {  
            if(l.k != 0) {  
                CGLine newLine = new CGLine(-1/l.k, p.y -(-1/l.k)*p.x);  
                target = getCrossPoint(l, newLine);  
            } else {
                target = new CGPoint(p.x, l.b);  
            }  
        } else {
            target = new CGPoint(l.extraX, p.y);  
        }  
        return target;
    }  
    public static CGPoint getCrossPoint(CGLine l1, CGLine l2) {
        double x, y;
        if(l1.iskExists() && l2.iskExists()) {  
            x = (l2.b - l1.b) / (l1.k - l2.k);  
            y = l1.k * x + l1.b;  
        } else if(!l1.iskExists() && l2.iskExists()) {  
            x = l1.extraX;  
            y = l2.k * x + l2.b;  
        } else if(l1.iskExists() && !l2.iskExists()) {  
            x = l2.extraX;  
            y = l1.k * x + l1.b;  
        } else {  
            x = 0;
            y = 0;  
        }  
        return new CGPoint(x, y);
    }  
  

    public static CGPoint getNearestPoint(CGPoint[] points, CGLine line) {  
        double minDistance = 0;  
        int minIndex = 0;  
        if(line.iskExists()) {  
            for(int i = 0; i < points.length; ++ i) {
                CGPoint p = points[i];  
                double d = Math.abs(line.k*p.x-p.y+line.b)/ Math.sqrt(Math.pow(line.k,2)+1);
                if(i == 0) {  
                    minDistance = d;
                }  
                if(d < minDistance) {  
                    minDistance = d;  
                    minIndex = i;  
                }  
            }  
        } else {  
            for(int i = 0; i < points.length; ++ i) {
                CGPoint p = points[i];  
                double d = Math.abs(p.x - line.extraX);
                if(i == 0) {  
                    minDistance = d;
                }
                if(d < minDistance) {  
                    minDistance = d;  
                    minIndex = i;  
                }  
            }  
        }  
        CGPoint dest = points[minIndex];  
        return dest;
    }  
      

    public static CGPoint getMiddlePoint(CGPoint p1, CGPoint p2) {  
        return new CGPoint((p1.x + p2.x) / 2.0f, (p1.y + p2.y) / 2.0f);  
    }  
      

    public static double pow(double d1, double d2) {  
        return Math.pow(d1, d2);
    }  
    public static double sqrt(double d) {  
        return Math.sqrt(d);
    }  
    public static double sin(double theta) {  
        return Math.sin(theta);
    }  
    public static double cos(double theta) {  
        return Math.cos(theta);
    }  
      

    public static CGPoint[] getWhatIWanted(CGPoint p1, CGPoint p2, double radius) {  
        CGPoint[] target = new CGPoint[2];  
        CGPoint pMiddle = p1;//getMiddlePoint(p1, p2);  

        CGLine l1 = new CGLine(p1, p2);  
        if(l1.iskExists()) {  
            if(l1.k != 0) {  
                double A = pow(l1.k, 2) + 1;
                double B = 2 * (l1.k * l1.b - l1.k * pMiddle.y - pMiddle.x);  
                double C = pow(pMiddle.x, 2) + pow((l1.b - pMiddle.y), 2) - pow(radius, 2);  
                double delta = pow(B, 2) - 4 * A * C;  
                  
                if(delta < 0) {
                    target[0] = new CGPoint(pMiddle.x, pMiddle.y - radius);
                    target[1] = new CGPoint(pMiddle.x, pMiddle.y + radius);  
                } else {  
                    double x1 = (-B + sqrt(delta)) / (2 * A);  
                    double y1 = l1.k * x1 + l1.b;  
                    target[0] = new CGPoint(x1, y1);  
                      
                    double x2 = (-B - sqrt(delta)) / (2 * A);  
                    double y2 = l1.k * x2 + l1.b;  
                    target[1] = new CGPoint(x2, y2);  
                }  
            } else {  
                target[0] = new CGPoint(pMiddle.x, pMiddle.y - radius);  
                target[1] = new CGPoint(pMiddle.x, pMiddle.y + radius);  
            }  
        } else {  
            target[0] = new CGPoint(pMiddle.x - radius, pMiddle.y);  
            target[1] = new CGPoint(pMiddle.x + radius, pMiddle.y);  
        }  
        return target;
    }  
}
